#include "auto_reply_cache.h"

#include <string>
#include <fstream>
#include <boost/regex.hpp>

#include "base/logging.h"
#include "base/config_reader.h"

#include "thread_manager.h"

namespace im {

using apache::thrift::concurrency::Runnable;
class ReloadTask : public Runnable  {
 public:
  ReloadTask(){}
  virtual void run() {
    AutoReplyCache::Instance().Reload();
    GetTimerManager()->add(boost::shared_ptr<Runnable>(new ReloadTask()), 3 * 1000);
  }
};


AutoReplyCache::AutoReplyCache() {
  ConfigReader config("../conf/im_jd_robot_service.conf");
  GetTimerManager()->add(boost::shared_ptr<Runnable>(new ReloadTask()), 3 * 1000);
}

std::string AutoReplyCache::GetReply(const std::string & question) const {
  boost::shared_lock<boost::shared_mutex> rlock(qa_map_mutex_);

  std::map<std::string, std::string>::const_iterator it = qa_map_.begin();
  for(; it != qa_map_.end(); ++it) {
    boost::cmatch what;
    boost::regex re(it->first, boost::regex::perl | boost::regex::icase);
    if (boost::regex_match(question.c_str(), what, re)) {
      return it->second;
    } else {
      LOG_DEBUG("regex " << it->first << " not match question " << question);
    }
  }

  static std::string empty;
  return empty;
}

int AutoReplyCache::Reload() {
  std::map<std::string, std::string> qa_map;
  LOG_INFO("start AutoReplyCache::Reload()");

  std::ifstream qa_file("../conf/im_jd_robot_questions.txt");
  if (!qa_file) {
    LOG_WARN("open quesiton file ../conf/im_jd_robot_questions.txt error.");
    return -1;
  }
  LOG_INFO("open quesiton file ../conf/im_jd_robot_questions.txt ok.");

  const static int BUF_SIZE = 2048;
  char line[BUF_SIZE];
  while(qa_file.getline(line, BUF_SIZE - 1)) {
    line[BUF_SIZE - 1] = 0;
    char * p = strstr(line, "====>");
    if (p) {
      LOG_DEBUG("load question line " << line);
      *p = '\0';
      qa_map.insert(std::make_pair(std::string(line), std::string(p + 5)));
    } else {
      LOG_WARN("bad question line " << line);
    }
  }

  {
    boost::unique_lock<boost::shared_mutex> wlock(qa_map_mutex_);
    qa_map_.swap(qa_map);
  }
  return 0;
}

}

